import { Progress, Card, Button } from 'antd';
import { useCallback } from 'react';
import { useRef } from 'react';
import { useEffect, useState } from 'react';
/**
 * 模拟进度，产生不断逼近 100% 的进度值，交给回调函数。
 * @param { (percent: number) => void} fn 处理生成的进度值回调函数。必须调用返回的stop函数，否则将一直被调动
 * @param { (rate:number )=>number} strategy 决定计算策略
 * @param resistance 值越大，进度增长的越慢
 * @returns stop函数
 */
function imitateProgress(fn, strategy, resistance = 1000) {
  const baseTime = Date.now();
  let validate = true;
  let p = 0;

  const forward = () => {
    setTimeout(() => {
      if (validate) {
        p = strategy((Date.now() - baseTime) / resistance);
        fn(p);
        forward();
      }
    }, 16);
  };
  forward();

  /**
   * @param {'success' | 'error'} flag 传入success，将逐步设置进度到100%，避免生硬
   */
  return function stopImitate(flag) {
    return new Promise((resolve) => {
      validate = false;
      if (flag === 'success') {
        // 迅速到达100
        const step = Math.max(0.1, (100 - p) / 22);
        console.log('current:', p, 'step:', step);
        const _fwd = () => {
          setTimeout(() => {
            p = Math.min(100, p + step);
            fn(p);
            if (p < 100) {
              _fwd();
            } else {
              resolve(0);
            }
          }, 16);
        };
        _fwd();
      } else {
        resolve(0);
      }
    });
  };
}

export default function ProgressImitate() {
  const [p1, setP1] = useState(0);
  const [p2, setP2] = useState(0);
  const [p3, setP3] = useState(0);
  const [loading, setLoading] = useState(false);

  /**
   * @type {React.MutableRefObject<Array<(flag: "success" | "error") => Promise<any>>>}
   */
  const stopRef = useRef([() => 0, () => 0, () => 0]);

  const start = useCallback(async () => {
    setLoading(true);

    const stop1 = imitateProgress(setP1, (r) => (Math.atan(r) * 200) / Math.PI);
    const stop2 = imitateProgress(setP2, (r) => (1 - 0.5 ** r) * 100);
    const stop3 = imitateProgress(setP3, (r) => Math.tanh(r / 1.820478453253675) * 100);
    stopRef.current = [stop1, stop2, stop3];
  }, []);

  const stop = useCallback(async () => {
    await Promise.all(stopRef.current.map((f) => f('success')));
    setLoading(false);
  }, []);

  const format = useCallback(
    /**
     * @param {number} [p]
     */
    (p) => {
      return (p || 0).toFixed(2) + '%';
    },
    []
  );
  useEffect(() => {
    // corsTest();
  }, []);

  return (
    <Card title="进度条模拟（不断逼近100%）">
      {loading ? (
        <Button onClick={stop} style={{ width: '6em' }}>
          stop
        </Button>
      ) : (
        <Button onClick={start} style={{ width: '6em' }}>
          start
        </Button>
      )}
      <Progress percent={50} format={format} />
      反正切方案：
      <Progress percent={p1} format={format} />
      指数方案：
      <Progress percent={p2} format={format} />
      双曲正切方案：
      <Progress percent={p3} format={format} />
    </Card>
  );
}
